<template>
  <div class="token-debug-container">
    <h1>Token诊断页面</h1>
    
    <!-- Token状态信息 -->
    <div class="token-info">
      <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;">
        <h2>Token状态信息</h2>
        <el-button type="primary" size="small" @click="checkTokenStatus">刷新状态</el-button>
      </div>
      <p><strong>Token名称:</strong> {{ tokenName }}</p>
      <p><strong>存储位置:</strong> {{ storage }}</p>
      <p><strong>存储Key:</strong> {{ tokenTableName }}</p>
      <p><strong>Store中的Token:</strong> <span :style="{ color: storeToken ? 'green' : 'red' }">{{ storeToken ? '已设置' : '未设置' }}</span></p>
      <p><strong>存储中的Token:</strong> <span :style="{ color: storageToken ? 'green' : 'red' }">{{ storageToken ? '已设置' : '未设置' }}</span></p>
      
      <div v-if="storeToken" class="token-detail">
        <h3>Store中的Token详情:</h3>
        <p><strong>Token值:</strong> {{ storeToken }}</p>
        <p><strong>Token长度:</strong> {{ storeToken.length }}</p>
        <p><strong>Token是否过期:</strong> <span :style="{ color: isTokenExpired ? 'red' : 'green' }">{{ isTokenExpired ? '已过期' : '未过期' }}</span></p>
        <p><strong>过期时间:</strong> {{ tokenExpireTime }}</p>
        <p v-if="!isTokenExpired && tokenExpireTime !== '无过期时间' && tokenExpireTime !== 'Token格式错误' && !tokenExpireTime.includes('解析失败')"><strong>剩余时间:</strong> <span style="color: green;">{{ remainingTime }}</span></p>
      </div>
      
      <div v-if="storageToken" class="token-detail">
        <h3>存储中的Token详情:</h3>
        <p><strong>Token值:</strong> {{ storageToken }}</p>
        <p><strong>Token长度:</strong> {{ storageToken.length }}</p>
      </div>
    </div>
    
    <!-- 请求头测试 -->
    <div class="header-test">
      <h2>请求头测试</h2>
      <el-button type="primary" @click="testRequestHeaders">测试请求头</el-button>
      
      <div v-if="requestHeaders" class="headers">
        <h3>请求头信息:</h3>
        <pre>{{ requestHeaders }}</pre>
      </div>
    </div>
    
    <!-- API端点测试 -->
    <div class="api-test">
      <h2>API端点测试</h2>
      <el-button type="primary" @click="testCourseApi">测试课程API</el-button>
      <el-button type="success" @click="testMenuApi">测试菜单API</el-button>
      <el-button type="warning" @click="runConsoleTest">控制台测试</el-button>
      
      <div v-if="apiTestResult" class="result">
        <h3>API测试结果:</h3>
        <pre>{{ JSON.stringify(apiTestResult, null, 2) }}</pre>
      </div>
    </div>
    
    <!-- 手动设置Token测试 -->
    <div class="manual-test">
      <h2>手动设置Token测试</h2>
      <el-input 
        v-model="manualToken" 
        placeholder="输入Token值"
        style="width: 400px; margin-bottom: 10px;"
      ></el-input>
      <br>
      <el-button type="warning" @click="testWithManualToken">使用手动Token测试</el-button>
      
      <div v-if="manualTestResult" class="result">
        <h3>手动测试结果:</h3>
        <pre>{{ manualTestResult }}</pre>
      </div>
    </div>
    
    <!-- 刷新Token -->
    <div class="refresh-token">
      <h2>刷新Token</h2>
      <el-button type="success" @click="refreshUserToken">刷新用户Token</el-button>
      
      <div v-if="refreshResult" class="result">
        <h3>刷新结果:</h3>
        <pre>{{ refreshResult }}</pre>
      </div>
    </div>
    
    <!-- JWT过滤器测试 -->
    <div class="jwt-filter-test">
      <h2>JWT过滤器测试</h2>
      <el-button type="primary" @click="testJwtFilter">测试JWT过滤器</el-button>
      <el-button type="warning" @click="testWithoutToken">无Token测试</el-button>
      
      <div v-if="jwtFilterResult" class="result">
        <h3>JWT过滤器测试结果:</h3>
        <pre>{{ JSON.stringify(jwtFilterResult, null, 2) }}</pre>
      </div>
    </div>
    
    <!-- 返回按钮 -->
    <div class="back-section">
      <el-button @click="goBack">返回</el-button>
    </div>
  </div>
</template>

<script>
import { tokenName, storage, tokenTableName } from "@/config";
import store from "@/store";
import { getAccessToken } from "@/utils/accessToken";

export default {
  name: "CourseTest",
  data() {
    return {
      tokenName: tokenName,
      storage: storage,
      tokenTableName: tokenTableName,
      storeToken: null,
      storageToken: null,
      requestHeaders: null,
      manualToken: "",
      manualTestResult: null,
      refreshResult: null,
      apiTestResult: null,
      isTokenExpired: false,
      tokenExpireTime: "",
      remainingTime: "",
      jwtFilterResult: null
    };
  },
  created() {
    this.checkTokenStatus();
  },
  methods: {
    goBack() {
      this.$router.go(-1);
    },
    
    // 检查Token状态
    checkTokenStatus() {
      this.storeToken = store.getters["user/accessToken"];
      this.storageToken = getAccessToken();
      
      // 检查Token是否过期
      if (this.storeToken) {
        this.checkTokenExpiration(this.storeToken);
      }
      
      console.log("Token诊断信息:");
      console.log("Store Token:", this.storeToken);
      console.log("Storage Token:", this.storageToken);
      console.log("Token Name:", this.tokenName);
      console.log("Storage:", this.storage);
      console.log("Token Table Name:", this.tokenTableName);
    },
    
    // 检查Token是否过期
    checkTokenExpiration(token) {
      try {
        // 检查Token格式
        if (!token || typeof token !== 'string') {
          this.isTokenExpired = true;
          this.tokenExpireTime = "Token格式错误";
          return;
        }
        
        const parts = token.split('.');
        if (parts.length !== 3) {
          this.isTokenExpired = true;
          this.tokenExpireTime = "Token格式错误";
          return;
        }
        
        // 解析payload
        let payload;
        try {
          // 处理base64解码
          const base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/');
          const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
          }).join(''));
          payload = JSON.parse(jsonPayload);
        } catch (e) {
          // 如果上面的方法失败，尝试直接atob
          payload = JSON.parse(atob(parts[1]));
        }
        
        console.log("Token payload:", payload);
        
        if (!payload.exp) {
          this.isTokenExpired = false;
          this.tokenExpireTime = "无过期时间";
          return;
        }
        
        const currentTime = Math.floor(Date.now() / 1000);
        const expireTime = payload.exp;
        
        this.isTokenExpired = expireTime < currentTime;
        this.tokenExpireTime = new Date(expireTime * 1000).toLocaleString('zh-CN', {
          year: 'numeric',
          month: '2-digit',
          day: '2-digit',
          hour: '2-digit',
          minute: '2-digit',
          second: '2-digit'
        });
        
        console.log("Token过期检查:");
        console.log("当前时间:", new Date(currentTime * 1000).toLocaleString());
        console.log("过期时间:", this.tokenExpireTime);
        console.log("是否过期:", this.isTokenExpired);
        console.log("剩余时间:", this.isTokenExpired ? "已过期" : this.formatRemainingTime(expireTime - currentTime));
        
        this.remainingTime = this.formatRemainingTime(expireTime - currentTime);
        
      } catch (error) {
        console.error("解析Token失败:", error);
        this.isTokenExpired = true;
        this.tokenExpireTime = "解析失败: " + error.message;
      }
    },
    
    // 格式化剩余时间
    formatRemainingTime(seconds) {
      if (seconds <= 0) return "已过期";
      
      const days = Math.floor(seconds / (24 * 60 * 60));
      const hours = Math.floor((seconds % (24 * 60 * 60)) / (60 * 60));
      const minutes = Math.floor((seconds % (60 * 60)) / 60);
      
      if (days > 0) return `${days}天${hours}小时${minutes}分钟`;
      if (hours > 0) return `${hours}小时${minutes}分钟`;
      return `${minutes}分钟`;
    },
    
    // 测试请求头
    async testRequestHeaders() {
      try {
        console.log("测试请求头");
        this.requestHeaders = null;
        
        // 模拟请求拦截器的逻辑
        const config = {
          headers: {
            'Content-Type': 'application/json;charset=UTF-8'
          }
        };
        
        if (store.getters["user/accessToken"]) {
          config.headers[this.tokenName] = store.getters["user/accessToken"];
        }
        
        this.requestHeaders = JSON.stringify(config.headers, null, 2);
        console.log("请求头:", config.headers);
      } catch (error) {
        console.error("测试请求头失败:", error);
        this.requestHeaders = "错误: " + error.message;
      }
    },
    
    // 测试课程API
    async testCourseApi() {
      try {
        console.log("测试课程API");
        this.apiTestResult = null;
        
        // 方法1: 使用原始fetch请求
        console.log("=== 方法1: 原始fetch请求 ===");
        const token = localStorage.getItem('opsli-token');
        console.log("使用的Token:", token);
        
        const response = await fetch('http://127.0.0.1:7000/opsli-boot/api/v1/website/course/findPage?pageNo=1&pageSize=10', {
          method: 'GET',
          headers: {
            'T-Authorization': token,
            'Content-Type': 'application/json'
          }
        });
        
        console.log("响应状态:", response.status);
        console.log("响应头:", Object.fromEntries(response.headers.entries()));
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const responseText = await response.text();
        console.log("原始响应文本:", responseText);
        
        let data;
        try {
          data = JSON.parse(responseText);
        } catch (e) {
          console.error("JSON解析失败:", e);
          this.apiTestResult = {
            error: "JSON解析失败",
            rawResponse: responseText,
            status: response.status
          };
          return;
        }
        
        console.log("解析后的数据:", data);
        
        // 方法2: 使用API模块
        console.log("=== 方法2: 使用API模块 ===");
        const { getList } = await import("@/api/website/course/CourseManagementApi");
        const apiResult = await getList({ pageNo: 1, pageSize: 10 });
        
        this.apiTestResult = {
          method1: {
            status: response.status,
            data: data,
            headers: Object.fromEntries(response.headers.entries())
          },
          method2: {
            result: apiResult
          }
        };
        
        console.log("课程API测试完成");
      } catch (error) {
        console.error("课程API测试失败:", error);
        this.apiTestResult = {
          error: error.message,
          stack: error.stack,
          response: error.response ? {
            status: error.response.status,
            data: error.response.data,
            headers: error.response.headers
          } : null
        };
      }
    },
    
    // 测试菜单API
    async testMenuApi() {
      try {
        console.log("测试菜单API");
        this.apiTestResult = null;
        
        const { getRouterList } = await import("@/api/router");
        const result = await getRouterList();
        
        this.apiTestResult = JSON.stringify(result, null, 2);
        console.log("菜单API测试成功:", result);
      } catch (error) {
        console.error("菜单API测试失败:", error);
        this.apiTestResult = {
          error: error.message,
          response: error.response ? {
            status: error.response.status,
            data: error.response.data
          } : null
        };
      }
    },
    
    // 使用手动Token测试
    async testWithManualToken() {
      try {
        console.log("使用手动Token测试");
        this.manualTestResult = null;
        
        if (!this.manualToken) {
          this.manualTestResult = "请先输入Token值";
          return;
        }
        
        const axios = await import("axios");
        const config = {
          method: 'get',
          url: 'http://127.0.0.1:7000/opsli-boot/api/v1/website/course/findPage',
          params: { pageNo: 1, pageSize: 10 },
          headers: {
            'Content-Type': 'application/json;charset=UTF-8',
            [this.tokenName]: this.manualToken
          }
        };
        
        console.log("手动Token请求配置:", config);
        
        const response = await axios.default(config);
        this.manualTestResult = JSON.stringify(response.data, null, 2);
        console.log("手动Token测试成功:", response.data);
      } catch (error) {
        console.error("手动Token测试失败:", error);
        this.manualTestResult = {
          error: error.message,
          response: error.response ? {
            status: error.response.status,
            data: error.response.data
          } : null
        };
      }
    },
    
    // 刷新用户Token
    async refreshUserToken() {
      try {
        console.log("刷新用户Token");
        this.refreshResult = null;
        
        const result = await store.dispatch("user/refreshUserPerms");
        
        if (result) {
          this.refreshResult = "Token刷新成功";
          this.checkTokenStatus(); // 重新检查Token状态
        } else {
          this.refreshResult = "Token刷新失败";
        }
      } catch (error) {
        console.error("刷新Token失败:", error);
        this.refreshResult = "刷新Token失败: " + error.message;
      }
    },
    
    // 控制台测试
    async runConsoleTest() {
      try {
        console.log("=== 开始控制台测试 ===");
        this.apiTestResult = null;
        
        const token = localStorage.getItem('opsli-token');
        console.log("当前Token:", token);
        
        // 测试1: 检查Token格式
        if (token) {
          const parts = token.split('.');
          console.log("Token部分数量:", parts.length);
          if (parts.length === 3) {
            try {
              const payload = JSON.parse(atob(parts[1]));
              console.log("Token payload:", payload);
              console.log("Token过期时间:", new Date(payload.exp * 1000));
              console.log("Token是否过期:", payload.exp < Math.floor(Date.now() / 1000));
            } catch (e) {
              console.error("Token解析失败:", e);
            }
          }
        }
        
        // 测试2: 直接fetch请求
        console.log("=== 测试2: 直接fetch请求 ===");
        const response = await fetch('http://127.0.0.1:7000/opsli-boot/api/v1/website/course/findPage?pageNo=1&pageSize=10', {
          method: 'GET',
          headers: {
            'T-Authorization': token,
            'Content-Type': 'application/json'
          }
        });

        console.log("响应状态:", response.status);
        console.log("响应头:", Object.fromEntries(response.headers.entries()));
        
        const responseText = await response.text();
        console.log("响应文本长度:", responseText.length);
        console.log("响应文本前200字符:", responseText.substring(0, 200));
        
        let data;
        try {
          data = JSON.parse(responseText);
          console.log("解析后的数据:", data);
        } catch (e) {
          console.error("JSON解析失败:", e);
          data = { error: "JSON解析失败", rawText: responseText };
        }
        
        // 测试3: 检查axios配置
        console.log("=== 测试3: 检查axios配置 ===");
        const axios = await import("axios");
        console.log("axios默认配置:", axios.default.defaults);
        
        this.apiTestResult = {
          token: {
            exists: !!token,
            length: token ? token.length : 0,
            format: token ? (token.split('.').length === 3 ? 'valid' : 'invalid') : 'none'
          },
          response: {
            status: response.status,
            statusText: response.statusText,
            headers: Object.fromEntries(response.headers.entries()),
            data: data,
            textLength: responseText.length
          },
          timestamp: new Date().toISOString()
        };
        
        console.log("=== 控制台测试完成 ===");
        console.log("测试结果:", this.apiTestResult);
        
      } catch (error) {
        console.error("控制台测试失败:", error);
        this.apiTestResult = {
          error: error.message,
          stack: error.stack,
          timestamp: new Date().toISOString()
        };
      }
    },
    
    // 测试JWT过滤器
    async testJwtFilter() {
      try {
        console.log("测试JWT过滤器");
        this.jwtFilterResult = null;
        
        const response = await fetch('http://127.0.0.1:7000/opsli-boot/api/v1/website/course/findPage?pageNo=1&pageSize=10', {
          method: 'GET',
          headers: {
            'T-Authorization': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiIxIiwidXNlcm5hbWUiOiJzeXN0ZW0iLCJuaWNrbmFtZSI6Iui2hee6p-euoeeQhuWRmCIsInRlbmFudElkIjoiMCIsImVtYWlsIjoic3lzdGVtIiwibG9naW5Gcm9tIjoiMCIsImxvZ2luSXAiOiIiLCJ0YWciOiIxIiwiaWF0IjoxNzUxODE1MzUwLCJleHAiOjE3NTE4MjI4NTB9.d4RIQmI92ErRUy-zhV3Th6ZWlPyi1Rw541qMtYlS9jI'
          }
        });
        
        console.log("响应状态:", response.status);
        console.log("响应头:", Object.fromEntries(response.headers.entries()));
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const responseText = await response.text();
        console.log("响应文本长度:", responseText.length);
        console.log("响应文本前200字符:", responseText.substring(0, 200));
        
        let data;
        try {
          data = JSON.parse(responseText);
          console.log("解析后的数据:", data);
        } catch (e) {
          console.error("JSON解析失败:", e);
          data = { error: "JSON解析失败", rawText: responseText };
        }
        
        this.jwtFilterResult = {
          status: response.status,
          statusText: response.statusText,
          headers: Object.fromEntries(response.headers.entries()),
          data: data,
          textLength: responseText.length
        };
        
        console.log("JWT过滤器测试完成");
      } catch (error) {
        console.error("JWT过滤器测试失败:", error);
        this.jwtFilterResult = {
          error: error.message,
          response: error.response ? {
            status: error.response.status,
            data: error.response.data
          } : null
        };
      }
    },
    
    // 测试无Token测试
    async testWithoutToken() {
      try {
        console.log("测试无Token测试");
        this.jwtFilterResult = null;
        
        const response = await fetch('http://127.0.0.1:7000/opsli-boot/api/v1/website/course/findPage?pageNo=1&pageSize=10', {
          method: 'GET',
          headers: {
            'T-Authorization': 'none'
          }
        });
        
        console.log("响应状态:", response.status);
        console.log("响应头:", Object.fromEntries(response.headers.entries()));
        
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}: ${response.statusText}`);
        }
        
        const responseText = await response.text();
        console.log("响应文本长度:", responseText.length);
        console.log("响应文本前200字符:", responseText.substring(0, 200));
        
        let data;
        try {
          data = JSON.parse(responseText);
          console.log("解析后的数据:", data);
        } catch (e) {
          console.error("JSON解析失败:", e);
          data = { error: "JSON解析失败", rawText: responseText };
        }
        
        this.jwtFilterResult = {
          status: response.status,
          statusText: response.statusText,
          headers: Object.fromEntries(response.headers.entries()),
          data: data,
          textLength: responseText.length
        };
        
        console.log("无Token测试完成");
      } catch (error) {
        console.error("无Token测试失败:", error);
        this.jwtFilterResult = {
          error: error.message,
          response: error.response ? {
            status: error.response.status,
            data: error.response.data
          } : null
        };
      }
    }
  }
};
</script>

<style scoped>
.token-debug-container {
  padding: 20px;
}

.token-info, .header-test, .api-test, .manual-test, .refresh-token, .jwt-filter-test {
  margin-bottom: 30px;
  padding: 15px;
  border: 1px solid #ddd;
  border-radius: 5px;
}

.token-detail, .headers, .result {
  margin-top: 15px;
  padding: 10px;
  border-radius: 5px;
  background-color: #f0f9ff;
  border: 1px solid #b3d8ff;
}

.back-section {
  margin-top: 30px;
  text-align: center;
}

pre {
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: 300px;
  overflow-y: auto;
}

h2 {
  color: #409EFF;
  margin-bottom: 10px;
}

h3 {
  color: #606266;
  margin-bottom: 5px;
}
</style>